/****************************************************************************\
 * @file     BR_Action.c
 * @author   傅帅
 * @date     2019/12/26
 * @brief    动作管理
 *
 ******************************************************************************
 * @attent   因为希望能和上位机Console结合，做到方便调每个动作的参数，
             故参数全定为float型，方便统一处理。
 ****************************************************************************/
#include <stdarg.h>
#include <stdlib.h>
#include "BR_Common.h"

/* 全局变量 */
BR_Action_t BR_ActionTbl[BR_configMAX_ACT_NUM];
uint8_t BR_ActionNum = 0;  // 当前已使用的动作数

/**
 * @brief  动作创建
 * @args   ActName     : 动作名
           ActionParNum: 参数数目
           ActionFunc  : 实际动作函数
   @retval 成功返回动作句柄, 失败返回NULL
 */
BR_ActionHandler_t BR_xActionCreate(char *ActionName, uint8_t ActionParNum, void ( * ActionFunc )(float *pPars))
{
    if(BR_ActionNum == BR_configMAX_ACT_NUM) return NULL;
    BR_ActionTbl[BR_ActionNum].ActionName = ActionName;
    BR_ActionTbl[BR_ActionNum].ActionParNum = ActionParNum;
    BR_ActionTbl[BR_ActionNum].pParsBuffer = malloc(ActionParNum * 4);  // 分配参数缓冲区
    BR_ActionTbl[BR_ActionNum].ActionFunc = ActionFunc;
    return &BR_ActionTbl[BR_ActionNum++];                               // 返回句柄后数目加一
}

/**
 * @brief  动作触发
 * @args   Action    : 动作句柄
            ...       : 不定长参数, 请传入float, 并保证数目应和ActionParNum一致
 */
void BR_vActionTrigger(BR_ActionHandler_t Action, ...)
{
    va_list pA;
    va_start(pA, Action);
    for(int i = 0; i < Action->ActionParNum; i++)
    {
        Action->pParsBuffer[i] = (float)va_arg(pA, double);             // 存入缓冲区，强制转换是因为...中的float会被升级为double
    }
    Action->ActionFunc(Action->pParsBuffer);
    va_end(pA);
}
